/**
 * 公式的http请求对象
 * */

import axios from 'axios';
import qs from 'qs';
import apiList from './api';
import Sign from './sign';
import store from '../../store';
import config from '@/config/config';
import {Message, Loading} from 'element-ui';

// axios 配置
const axiosConfig = {
  baseURL: config.api_url,
  timeout: 50000,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
};

// 加/解密对象
const sign = {
  // 解密
  decode: e => {
    return Sign.decode_post(e);
  },
  // 加密
  encode: e => {
    Sign.params = e;
    return Sign.encode_post();
  }
};

// 加载中弹出层
const load = {
  Loading: {},
  // 打开弹出层
  open: (el) => {
    let str = Math.random() * 9999 | 0;
    load.Loading[str] = Loading.service({target: el === true ? document.body : el,text:'加载中...',background:'rgba(0, 0, 0, 0.8)'});
    return str;
  },
  // 关闭弹出层
  close: (id) => {
    if (id === true) {
      Object.keys(load.Loading).map(e => {
        load.Loading[k].close();
      });
      load.Loading = {};
    } else if (load.Loading[id]) {
      setTimeout(() => {
        load.Loading[id].close();
        delete load.Loading[id];
      }, 200);
    }
  },
};

function initData(data) {
  let out = Object.assign({}, data);
  Object.keys(out).map(k => {
    if (!out[k] && out[k] !== 0) delete out[k];
  });
  return out;
}

function initConfig(config) {
  let out = Object.assign({
    isSign: false, // 是否需要加密
    loading: false, // 是否显示loading
    needXToken: true, // 是否需要xToken
    resDataKey: 'data', // 返回数据内容的key
    del:true // 是否需要删除空字符串
  }, axiosConfig, config);

  out.headers = Object.assign({
    ...axiosConfig.headers
  }, out.headers);
  out.headers['x-token'] = out.needXToken ? store.getters.xToken : '';

  return out;
}

// 是否正确返回
function isSuccessRes(res) {
  return res.code * 1 === config.ERR_OK;
}

class Index {

  http(url = '', data = {}, config = {}, method = 'post') {
    config = initConfig(config);
    let {isSign, loading, resDataKey,del} = config;
    let params = del? initData(data) : data
    delete config.isSign;
    delete config.loading;
    delete config.resDataKey;
    delete config.needXToken;
    delete config.del
    isSign && (params = JSON.parse(sign.encode(params)));
    loading && (loading = load.open(loading));
    params = qs.stringify(params);
    return axios[method](url, params, config).then(res => {
      loading && load.close(loading);
      let result = isSign ? sign.decode(res.data) : res.data;
      if (isSuccessRes(result)) {
        return resDataKey ? result[resDataKey] : result;
      } else {
        throw result;
      }
    });
  }

  post(url, data, config) {
    return this.http(url, data, config, 'post');
  }

  get(url, data, config) {
    return this.http(url, data, config, 'get');
  }

  test(...arg) {
    let [url, data, config, method] = arg;
    let configs = initConfig(Object.assign({...config}, {
      loading: false,
      resDataKey: '',
    }));
    let out = {};
    method = method || 'post';
    console.log(url, ':data:>', data);
    console.log(url, ':initData:>', initData(data));
    console.log(url, ':config:>', config);
    console.log(url, ':initConfig:>', initConfig({...config}));
    this.http(url, data, configs, method).then(res => {
      console.log(url, ':res:>', res);
      Object.assign(out, res);
      if (!Object.keys(out).length) out.status = true;
    }).catch(err => {
      Object.assign(out, err);
      if (!Object.keys(out).length) out.status = false;
      console.log(url, ':error:>', err);
    });
    return out;
  }

  $post(url, data, config) {
    config = config || {};
    config.isSign = true;
    return this.post(url, data, config);
  }

  download(url, params = {}, config = {}) {
    Object.keys(params).map(e => {
      // 去掉空的参数
      if (!params[e] && params[e] !== 0) {
        delete params[e];
      }
    });
    let data = params;
    if (config.isSign) {
      data = JSON.parse(sign.encode(params));
    }
    if (config.needXToken) {
      data['X-token'] = store.getters.xToken;
    }
    let pathData = [];
    Object.keys(data).map(k => {
      pathData.push(`${k}=${data[k]}`);
    });
    let api = /^https?/.test(url) ? '' : api_url;
    return api + url + '?' + pathData.join('&');
  }

  $err(err) {
    // 错误处理
    load.close(true);
    console.log(err);
    let msg = err.msg;
    if (!err.code) {
      msg = '网络错误！请稍后'
    }
    Message.error(msg);
  }

}

let http = new Index();
Object.assign(http, apiList);
export default http;